/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * File Name          : freertos.c
  * Description        : Code for freertos applications
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2025 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */

/* Includes ------------------------------------------------------------------*/
#include "FreeRTOS.h"
#include "task.h"
#include "main.h"
#include "cmsis_os.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "bsp.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN Variables */
static TaskHandle_t xHandleTaskStart = NULL;
static TaskHandle_t xHandleTaskUartRx = NULL;  // �������ڽ���������

SemaphoreHandle_t xUartMutex;    // ���ڱ���������Դ�Ļ�����

SemaphoreHandle_t xTxSemaphore;  // ���ڷ�����ɵ��ź���

// ���ڽ�����ر���
SemaphoreHandle_t xUartRxSemaphore = NULL;
QueueHandle_t xUartFrameQueue = NULL;

/* USER CODE END Variables */
/* Definitions for defaultTask */
osThreadId_t defaultTaskHandle;
const osThreadAttr_t defaultTask_attributes = {
  .name = "defaultTask",
  .stack_size = 128 * 4,
  .priority = (osPriority_t) osPriorityNormal,
};

/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN FunctionPrototypes */
static void AppTaskStart(void *argument);
static void AppTaskUartRx(void *argument);
/* USER CODE END FunctionPrototypes */

void StartDefaultTask(void *argument);

void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */

/**
  * @brief  FreeRTOS initialization
  * @param  None
  * @retval None
  */
void MX_FREERTOS_Init(void) {
  /* USER CODE BEGIN Init */
  /* USER CODE END Init */

  /* USER CODE BEGIN RTOS_MUTEX */
    /* add mutexes, ... */
    xUartMutex = xSemaphoreCreateMutex();
  /* USER CODE END RTOS_MUTEX */

  /* USER CODE BEGIN RTOS_SEMAPHORES */
    /* add semaphores, ... */
    xTxSemaphore = xSemaphoreCreateBinary();
    xUartRxSemaphore = xSemaphoreCreateBinary();  // �������ڽ����ź���
  /* USER CODE END RTOS_SEMAPHORES */

  /* USER CODE BEGIN RTOS_TIMERS */
    /* start timers, add new ones, ... */
  /* USER CODE END RTOS_TIMERS */

  /* USER CODE BEGIN RTOS_QUEUES */
    /* add queues, ... */
    xUartFrameQueue = xQueueCreate(10, sizeof(UartFrame));  // ����֡����
  /* USER CODE END RTOS_QUEUES */

  /* Create the thread(s) */
  /* creation of defaultTask */
  defaultTaskHandle = osThreadNew(StartDefaultTask, NULL, &defaultTask_attributes);

  /* USER CODE BEGIN RTOS_THREADS */
    /* add threads, ... */
    xTaskCreate(AppTaskStart,           /* ������  */
                "AppTaskStart",       /* ������    */
                512,                 	/* ����ջ��С����λword��Ҳ����4�ֽ� */
                NULL,                 /* �������  */
                osPriorityNormal6,    /* �������ȼ�*/
                &xHandleTaskStart);   /* ������  */
    // �������ڽ�������
    xTaskCreate(AppTaskUartRx,          /* ������  */
                "AppTaskUartRx",      /* ������    */
                512,                  /* ����ջ��С����λword��Ҳ����4�ֽ� */
                NULL,                 /* �������  */
                osPriorityNormal3,    /* �������ȼ������ڵ�����ƣ�*/
                &xHandleTaskUartRx);  /* ������  */
  /* USER CODE END RTOS_THREADS */

  /* USER CODE BEGIN RTOS_EVENTS */
    /* add events, ... */
  /* USER CODE END RTOS_EVENTS */

}

/* USER CODE BEGIN Header_StartDefaultTask */
/**
  * @brief  Function implementing the defaultTask thread.
  * @param  argument: Not used
  * @retval None
  */
/* USER CODE END Header_StartDefaultTask */
void StartDefaultTask(void *argument)
{
  /* USER CODE BEGIN StartDefaultTask */
    /* Infinite loop */
    for (;;) {
        osDelay(1);
    }

  /* USER CODE END StartDefaultTask */
}

/* Private application code --------------------------------------------------*/
/* USER CODE BEGIN Application */
/*
*********************************************************************************************************
*	�� �� ��: AppTaskUartRx
*	����˵��: ���ڽ������񣬴���DMA���յĲ���������
*	��    ��: argument - �������
*	�� �� ֵ: ��
* �� �� ��: osPriorityNormal3
*********************************************************************************************************
*/
static void AppTaskUartRx(void *argument)
{
    xSemaphoreGive(xTxSemaphore);
    //  UartFrame frame;
    uint16_t data_length;

    while (1) {
        // �ȴ��ź������ɿ����ж��ͷţ�
        if (xSemaphoreTake(xUartRxSemaphore, portMAX_DELAY) == pdTRUE) {
            // ������յ������ݳ���
            if (dma_current_pos >= dma_last_pos) {
                data_length = dma_current_pos - dma_last_pos;
            } else {
                data_length = UART_RX_BUFFER_SIZE - dma_last_pos + dma_current_pos;
            }

            // ������յ�������
            if (data_length > 0) {
                ProcessUartData(dma_last_pos, data_length);
            }

            dma_last_pos = dma_current_pos;
        }

        // ������ʱ���ó�CPU
        vTaskDelay(1);
    }
}

/*
*********************************************************************************************************
*	�� �� ��: AppTaskStart
*	����˵��: ����������������BSP����������
*	��    ��: ��
*	�� �� ֵ: ��
* �� �� ��: osPriorityNormal6
*********************************************************************************************************
*/
static void AppTaskStart(void *argument)
{
    uint8_t  ucCount = 0;
    uint32_t  ucCount1 = 0;
    /* ��ʼ������ */

    while (1) {
        /* ��Ҫ�����Դ���ĳ��� */
        /* 1ms ���� */
        bsp_RunPer1ms();

        /* 10ms ���� */
        if (++ucCount == 10) {
            ucCount = 0;
            bsp_RunPer10ms();
        }

        /* 1000ms ���� */
        if (++ucCount1 == 1000) {
            ucCount1 = 0;
            bsp_LedToggle(1);
        }

        vTaskDelay(1);
    }
}


/* USER CODE END Application */

